package com.stary.pay.alipay.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.stary.pay.wxpay.api.util.StringUtils;

/**
 * <p>工具类</p>
 * @author stary {@link stary1993@qq.com}
 * @since 2019-5-7
 */
public class AlipayUtils {

	private static final char UNDERLINE = '_';
	
	public static Logger getLogger() {
		return LoggerFactory.getLogger("« alipay api »");
	}
	/**
	 * map转换java对象
	 * @param map
	 * @param beanClass
	 * @return 
	 * @return java对象
	 * @throws Exception
	 */
	public static Object mapToObject(Map<String, ?> map, Class<?> beanClass) throws Exception {    
		if (map == null) {
			return null;    	        	
		} 	  
		Object obj = beanClass.newInstance();  	  
		Field[] childFields = obj.getClass().getDeclaredFields();
		Field[] superFields = obj.getClass().getSuperclass().getDeclaredFields();
		for (Field field : childFields) {    
			int mod = field.getModifiers();    
			if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){    
				continue;    
			}      
			field.setAccessible(true);
			field.set(obj, map.get(camelToUnderline(field.getName())));   
		}   
		for (Field field : superFields) {    
			int mod = field.getModifiers();    
			if(Modifier.isStatic(mod) || Modifier.isFinal(mod)){    
				continue;    
			}    
			field.setAccessible(true);    
			field.set(obj, map.get(camelToUnderline(field.getName())));   
		}   
		return obj;    
	} 
	/**
	 * java bean 转化 map
	 * @param javaBean
	 * @return
	 * @throws Exception 
	 */
	public static Map<String, Object> beanToMap(Object javaBean) throws Exception {
		Map<String, Object> data=new HashMap<>();
		// 获取javaBean属性
		BeanInfo beanInfo = Introspector.getBeanInfo(javaBean.getClass());
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		if (propertyDescriptors != null && propertyDescriptors.length > 0) {
			String propertyName = new String(); // javaBean属性名
			Object propertyValue = new Object(); // javaBean属性值
			for (PropertyDescriptor pd : propertyDescriptors) {
				propertyName = pd.getName();
				if (!propertyName.equals("class")) {
					Method readMethod = pd.getReadMethod();
					propertyValue = readMethod.invoke(javaBean, new Object[0]);
					data.put(propertyName, propertyValue);
				}
			}
		}
		return data;
	}
	/**
	 * 驼峰格式字符串转换为下划线格式字符串 
	 * @param field 字段
	 * @return
	 */
	public static String camelToUnderline(String field) {
		if (StringUtils.isEmpty(field)) {
			return "";
		}
		int len = field.length();
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c = field.charAt(i);
			if (Character.isUpperCase(c)) {
				sb.append(UNDERLINE);
				sb.append(Character.toLowerCase(c));
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	/**
	 * 下划线格式字符串转换为驼峰格式字符串
	 * @param field 字段
	 * @return
	 */
	public static String underlineToCamel(String field) {
		if (StringUtils.isEmpty(field)) {
			return "";
		}
		int len = field.length();
		StringBuilder sb = new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c = field.charAt(i);
			if (c == UNDERLINE) {
				if (++i < len) {
					sb.append(Character.toUpperCase(field.charAt(i)));
				}
			} else {
				sb.append(c);
			}
		}
		return sb.toString();
	}

	/**
	 * 下划线格式字符串转换为驼峰格式字符串2
	 * @param field 字段
	 * @return
	 */
	public static String underlineToCamel2(String field) {
		if (StringUtils.isEmpty(field)) {
			return "";
		}
		StringBuilder sb = new StringBuilder(field);
		Matcher mc = Pattern.compile("_").matcher(field);
		int i = 0;
		while (mc.find()) {
			int position = mc.end() - (i++);
			sb.replace(position - 1, position + 1, sb.substring(position, position + 1).toUpperCase());
		}
		return sb.toString();
	}
}
